Skip to content

Sync ako/mxcli: fix the red 11.14/11.15 nightly; ALTER PAGE SET of pluggable attribute properties; inherited cross-module associations - #1639

Merged
ako merged 8 commits into
mendixlabs:mainfrom
ako:main
Oct 23, 2026
Merged

ako merged 8 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into upstream: 4 commits from fork PRs ako#1641, ako#1642 and ako#1643.

Nightly: 11.14 and 11.15 legs green again (ako#1642)

The upstream nightly is red on the Mendix 11.14.0 and 11.15.0 legs (run 39915484754):

--- FAIL: TestRunLifecycle_DetachStatusExecWaitStop
    cmd_run_lifecycle_integration_test.go:157: wait (Mendix 11.14+): want build #2 to fail with the
    serve-rebuild hint; exit 0, "applied: build #2 via restart in 48.1s (runtime restarted; browser sessions dropped)"
  • The test was out of date; mxcli itself is fine. run --local --watch now restarts mxbuild --serve when its incremental build drops dist/pages, so on 11.14+ build DROP ATTRIBUTE will trigger .mxunit ref empty error #2 applies via that restart instead of failing.
  • On 11.14+, wantBuild2 now requires build DROP ATTRIBUTE will trigger .mxunit ref empty error #2 to apply and the run log to show the recovery ("cannot build this change incrementally"). If a future mxbuild builds incrementally again, the test still fails and says so.
  • Verified locally on 11.14.0:
    • The old test fails with the nightly's exact message.
    • The new test passes all six steps.
    • With the restart branch in serve_recovery.go stubbed out, it fails as the control.
    • 11.15.0 wasn't run locally, but it failed identically in the nightly and goes through the same code path.
  • Not affected: the non-gating Mendix 9.24 job also fails in that run. It failed the day before too, so it's unrelated.

ALTER PAGE SET binds a pluggable widget's attribute property (refs #1591)

  • set (eventDataAttribute: JsonData) on chart1, and $Param.Attr, now work. Before, every spelling was refused, at check and at exec, so changing one binding meant rewriting the whole widget.
  • It binds with CREATE's own rules:
    • The mutator reports the property's kind, its datasource link and the surrounding data scopes. The executor then binds the value with the same functions CREATE uses, including the CE1613 and CE7247 refusals, word for word.
    • The mutator writes the AttributeRef and SourceVariable. The SourceVariable is nulled when the binding returns to the context object.
  • check --references dry-runs the same path, so check and exec agree.

A bare member name resolves to an association inherited from another module

  • The problem: over HR.Emp extends Other.Person, find $l by Other.Person_Dept = $d builds, but describe prints it as by Person_Dept. Executed as a new microflow, that passed check -p and exec, then failed mx check with CE1613 "The selected attribute 'HR.Emp.Person_Dept' no longer exists". Re-running over the stored flow reported "Unchanged", which hid it.
  • The fix: the new resolveInheritedAssociation walks the generalization chain for an ancestor's association in another module. It is tried after the inherited-attribute lookup, so an attribute of the same name still wins. Describe's short output now executes to the same member.
  • This follows up the System-module instance of the same drift, which is already upstream

claude and others added 8 commits October 23, 2026 07:33
`alter page … set (eventDataAttribute: …) on chart1` was refused for every
spelling: "pluggable property "eventDataAttribute" holds a value of kind
Attribute, which ALTER cannot set from a plain value", and `$Ctx.EventData`
failed at parse as "takes a plain value, not an expression". One binding
could only be changed by rewriting the whole widget.

Which entity a bare name belongs to is the widget's binding rule, not a fact
of the BSON the page mutator holds. So the mutator now describes the property
(PluggablePropertyScope: kind, datasource link, linked and enclosing scopes)
and the executor binds the value with CREATE's own functions:
resolveBindingScope, misboundAttributeError (the CE1613 and CE7247 refusals,
word for word) and parameterVariable for `$Param.Attr`. It hands the mutator
a backend.AttributeBinding, which writes the AttributeRef and the
SourceVariable, null when the binding returns to the context object. The
visitor lets the strict `$Param.Attr` shape through; on any other property
the executor refuses it. check --references dry-runs the same path.

Measured on mxbuild 11.12.5: `$Ctx.EventData` and a bare `JsonData` set
through ALTER build at 0 errors and describe back as written. Binding back
to JsonData with the stale $Ctx SourceVariable left in place is CE7247.

Fixes #1622.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZbx4k5eUbdTGQEcBaWFdM
The nightly's 11.14.0 and 11.15.0 legs went red in
TestRunLifecycle_DetachStatusExecWaitStop: "want build #2 to fail with the
serve-rebuild hint; exit 0, applied: build #2 via restart". cf135bf made the
watch loop restart mxbuild --serve and build on the fresh process when an
incremental build fails for want of client source, so on 11.14+ build #2 now
applies where it used to fail with the hint. The lifecycle test only runs in
the nightly (it needs a cached mxbuild and a runtime), so the PR that changed
the behaviour never ran it.

On 11.14+ the steps that wait for build #2 now require it to apply and the
run log to show the recovery ("cannot build this change incrementally"), so a
future mxbuild that builds incrementally again still fails this branch and
says it should go. The boot-race step keeps accepting any applied build #2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GeAhBjRBm5vN2ik3ddvVWW
…ther module

Over HR.Emp extends Other.Person, describe prints
`find $l by Other.Person_Dept = $d` as `find $l by Person_Dept = $d`.
The builder looked a bare member up only in the list entity's module, so
executing that description as a new microflow, or writing the name short
by hand in a find or a create, stored the attribute HR.Emp.Person_Dept:
check -p and exec passed, then mxbuild failed with
[CE1613] "The selected attribute 'HR.Emp.Person_Dept' no longer exists."
(11.12.5, #1637). Re-running over the stored flow said
"Unchanged", so only a rebuild showed it.

An association lives in its FROM entity's module, so one inherited from
a generalization in another module is not in the specialization's.
resolveInheritedAssociation walks the generalization chain, as
resolveAttributeInEntityHierarchy already does for attributes, and is
tried after it, so an inherited attribute of the same name still wins.
describe's output is unchanged; the member speller, which shortens only
when the short name resolves to the same member, now agrees with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XD4JpQem7z5pjk2WuYRqf
…rve failure

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GeAhBjRBm5vN2ik3ddvVWW
fix: ALTER PAGE SET can bind a pluggable widget's attribute property
…ues-bkrdmk

fix: a bare member name resolves to an association inherited from another module (CE1613)
…5joqyu

test(run): expect build #2 to apply via mxcli's serve restart on 11.14+
@ako
ako merged commit aa6b422 into mendixlabs:main Oct 23, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants